import { View } from '@tarojs/components'
import { forwardRef, useImperativeHandle } from 'react'
import { useLoad } from '@tarojs/taro'
import { FormItemConfig } from '@/BtComponents/BtCustomForm'
import utils from '@/utils'
import Validator from './validator'
import { formContextProvider } from './formContextProvider'
import './index.scss'

interface BtFormProps {
  children: React.ReactNode
  model: any
  rules: any
  config?: FormItemConfig[]
  /** 自定义类名 */
  className?: string
}

function BtForm ( {children, model, rules, className = '', config = []}: BtFormProps, ref) {
  const [state, dispatch] = formContextProvider.useTracked()

  useLoad(() => {
    dispatch({ type: "addRules", rules})
  })

  const validate = async () => {
    // 过滤不展示的字段校验
    const formRules = filterFormRules()
    validateFields()
    const validator = new Validator(formRules)
    const errs = await validator.validate(model)
    toastErrsMsg(errs)
    return errs
  }

  const toastErrsMsg = (errs: any) => {
    if (errs && errs.length > 0) {
      const msg = errs[0].message
      utils.$toast(msg)
    }
  }

  const validateFields = async() => {
    const promises = state.fields.map(async field => {
      const rule = {}
      if (rules[field.prop]) {
        rule[field.prop] = rules[field.prop]
      }
      const validator = new Validator(rule)
      const errs = await validator.validate(model)
      const msg = (errs && errs[0].message) || ''
      field.setErrMsg(msg)
    })
    
    try {
      await Promise.all(promises)
    } catch (error) {
      console.error('Validation error:', error)
    }
  }

  const filterFormRules = () => {
    const formRules = JSON.parse(JSON.stringify(rules))
    config.forEach(item => {
      if (item.show === false) {
        delete formRules[item.prop || '']
      }
    })
    return formRules
  }

  useImperativeHandle(ref, () => {
      return {
        validate
      };
    }
  );

  return (
    <View className={`form ${className}`}>
      <View>{children}</View>
    </View>
  )
}

const ChildFun = forwardRef(BtForm)
export default ChildFun
